Technical Q&A QA1313
paramErr returned from ConvertMovieToFile when exporting to .wav


Q: SndSnip_ConvertWAVEFormats のコードを使って 16ビット 44.1kHz ムービーのサウンドトラックを 8 ビット 22kHz の .wav ファイルに変換しようとしていますが、MovieExportSetSampleDescription からエラーが返されていない場合でも、ConvertMovieToFile から必ず paramErr(-50)が返されます。要件に合わせてサウンド記述を変更していますが(下記参照)、何が間違っているのでしょうか。

(**myDesc).descSize = sizeof(SoundDescription);
(**myDesc).sampleSize = 8;
(**myDesc).sampleRate = rate22050hz;
(**myDesc).dataFormat = k8BitOffsetBinaryFormat;

A: SndSnip_ConvertWAVEFormats はこれまで、サウンド記述の numChannels の値を設定しませんでした。その結果、デフォルトの値として間違った値の 0 が使われました。numChannelssampleRate または sampleSize のいずれかの値が 0 であると、サウンドエクスポートコンポーネントによって必ず paramErr が返されるので、.wav ファイルへのエクスポートに限らず、コードは影響を受けるはずです。

リスト 1 に、関数の中で、指摘のあったサウンド記述を使用する方法を示します。

リスト 1. MyConvertToWAV

OSErr MyConvertToWAV(Movie theMovie, FSSpec *theFile)
{
ComponentInstance      myComponent = NULL;
SoundDescriptionHandle myDesc = NULL;
ComponentResult        myErr = badComponentType;

// エクスポートコンポーネントを開く: .wav ファイルへのサウンドエクスポータ
myComponent = OpenDefaultComponent(MovieExportType, kQTFileTypeWave);

// コンポーネントが見つからない場合には -2005 エラーを返す
if (myComponent == NULL) goto bail; 

// サウンド記述を作成し、値を埋める
myDesc = (SoundDescriptionHandle)NewHandleClear(sizeof(SoundDescription));
if (myDesc == NULL) {
myErr = MemError();
goto bail;
  }

// 使用するフォーマット。.wav の dataFormat は次のいずれか。
// k8BitOffsetBinaryFormat または k16BitLittleEndianFormat 
(**myDesc).descSize = sizeof(SoundDescription);
(**myDesc).numChannels = 2;
(**myDesc).sampleSize = 8;
(**myDesc).sampleRate = rate22050hz; 
(**myDesc).dataFormat = k8BitOffsetBinaryFormat;

// エクスポートコンポーネントに対して、サウンド記述の
// サウンド特性を使用することを伝える
myErr = MovieExportSetSampleDescription(myComponent,
(SampleDescriptionHandle)myDesc,
SoundMediaType);
if (myErr != noErr) goto bail;
 
// ムービーをファイルにエクスポートする
myErr = ConvertMovieToFile(theMovie, // 変換対象ムービー
NULL,     // 全トラック
theFile,  // 出力ファイル
kQTFileTypeWave,        // ファイルタイプ(.wav)
FOUR_CHAR_CODE('TVOD'), // ファイルのクリエータ
smSystemScript,         // スクリプト
NULL, // リソース ID は返さない
0L,   // フラグはなし(つまり、「設定」ダイアログはなし)
myComponent); // エクスポートコンポーネント

bail:
// 割り当てた記憶領域があれば解放する
if (myComponent != NULL)
CloseComponent(myComponent);
       
if (myDesc != NULL)
DisposeHandle((Handle)myDesc);

return myErr;
}



[2003 年 10 月 6 日]